{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": null,
   "source": [
    "https://www.bilibili.com/video/BV1Mi4y1P7ta?from=search&seid=10235371555235529451&spm_id_from=333.337.0.0"
   ],
   "outputs": [],
   "metadata": {}
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "source": [
    "import tensorflow as tf"
   ],
   "outputs": [],
   "metadata": {}
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "source": [
    "class CGAN():\r\n",
    "\r\n",
    "    def __init__(self):\r\n",
    "        # 写入输入维度\r\n",
    "        self.img_rows = 28\r\n",
    "        self.img_cols = 28\r\n",
    "        self.img_channels = 1\r\n",
    "        self.img_shape = (self.img_rows,self.img_cols,self.img_channels)\r\n",
    "\r\n",
    "        self.num_classes = 10  # 类别数\r\n",
    "        self.latent_dim = 100 # 随机噪声向量维度\r\n",
    "\r\n",
    "    def build_generator(self):\r\n",
    "\r\n",
    "        # 输入随机向量与条件 生成图片\r\n",
    "        model = tf.keras.Sequential()\r\n",
    "\r\n",
    "        model.add(tf.keras.layers.Input(shape=(self.latent_dim)))\r\n",
    "        model.add(tf.keras.layers.Dense(256))\r\n",
    "        model.add(tf.keras.layers.LeakyReLU(alpha=0.2))\r\n",
    "        model.add(tf.keras.layers.BatchNormalization(momentum=0.8))\r\n",
    "\r\n",
    "        model.add(tf.keras.layers.Dense(512))\r\n",
    "        model.add(tf.keras.layers.LeakyReLU(alpha=0.2))\r\n",
    "        model.add(tf.keras.layers.BatchNormalization(momentum=0.8))\r\n",
    "\r\n",
    "        model.add(tf.keras.layers.Dense(1024))\r\n",
    "        model.add(tf.keras.layers.LeakyReLU(alpha=0.2))\r\n",
    "        model.add(tf.keras.layers.BatchNormalization(momentum=0.8))\r\n",
    "\r\n",
    "        # 随机向量最后一层输出,使用tanh激活，最后reshape为图片形状\r\n",
    "        model.add(tf.keras.layers.Dense(self.img_rows*self.img_cols*self.img_channels,activation='tanh'))\r\n",
    "        model.add(tf.keras.layers.Reshape(self.img_shape))\r\n",
    "\r\n",
    "        model.summary()  # 记录参数情况\r\n",
    "\r\n",
    "        noise = tf.keras.layers.Input(shape=self.latent_dim)  # 噪声的输入\r\n",
    "        label = tf.keras.layers.Input(shape=(1),dtype='int32')  # 这里的标签就是一个整数值，还没经过ont-hot或者embedding\r\n",
    "        _label_embedding = tf.keras.layers.Embedding(self.num_classes,self.latent_dim)(label)  # 将0-9这10个数字映射到100维,注意Embedding层会保留原维度。即变成(,1,100)了\r\n",
    "        label_embedding = tf.keras.layers.Flatten()(_label_embedding) # 将其转成(,100)形状\r\n",
    "\r\n",
    "        # 合并图片与标签，这里使用的不是concat而是multiply将两个向量关联在一起\r\n",
    "        model_input = tf.keras.layers.Multiply()([noise,label_embedding])  # 对应位置相乘，得到最终向量形状(,100) 与Sequential要求输入形状保持一致\r\n",
    "  \r\n",
    "        img = model(model_input)  # 直接将输入传给模型。\r\n",
    "\r\n",
    "        return tf.keras.Model([noise,label],img)  # 模型输入与输出"
   ],
   "outputs": [],
   "metadata": {}
  }
 ],
 "metadata": {
  "orig_nbformat": 4,
  "language_info": {
   "name": "python",
   "version": "3.7.1",
   "mimetype": "text/x-python",
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "pygments_lexer": "ipython3",
   "nbconvert_exporter": "python",
   "file_extension": ".py"
  },
  "kernelspec": {
   "name": "python3",
   "display_name": "Python 3.7.1 64-bit ('KerasEnv': virtualenv)"
  },
  "interpreter": {
   "hash": "49709926ca079d7fc3208f0b0481edbe733516c473689c5f1439ce0f2246de88"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}